package com.ruoyi.customer.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.customer.SentMessage;
import com.ruoyi.customer.common.*;
import com.ruoyi.customer.domain.Customer;
import com.ruoyi.customer.domain.Remark;
import com.ruoyi.customer.domain.UserCustomerCount;
import com.ruoyi.customer.domain.vo.CustomerVo;
import com.ruoyi.customer.mapper.CustomerMapper;
import com.ruoyi.customer.mapper.RemarkMapper;
import com.ruoyi.customer.mapper.TotalComsterMapper;
import com.ruoyi.customer.service.DisCommonService;
import com.ruoyi.disCustomer.domain.TCustomerDisRecord;
import com.ruoyi.disCustomer.mapper.TCustomerDisRecordMapper;
import com.ruoyi.enums.BusTypeEnum;
import com.ruoyi.enums.CompanyStatusEnum;
import com.ruoyi.enums.CustomerStatusEnum;
import com.ruoyi.system.service.ISysConfigService;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class DisCommonServiceImpl implements DisCommonService {


    private final CustomerMapper customerMapper;

    private final TotalComsterMapper totalComsterMapper;

    private final TCustomerDisRecordMapper disRecordMapper;

    private final RemarkMapper remarkMapper;

    private final ISysConfigService sysConfigService;


    @Override
    public List<DisCustomerBo> checkDataDept(DisCustomerRequestBo requestBo, String operationType) {

        List<DisCustomerBo> disCustomerBos = requestBo.getDisCustomerBos();
        if (CollectionUtils.isEmpty(disCustomerBos)) {
            throw new ServiceException("客户信息参数缺失");
        }

        List<DisDeptBo> deptBos = requestBo.getDeptBos();
        if (CollectionUtils.isEmpty(deptBos)) {
            throw new ServiceException("部门信息参数缺失");
        }

        return check(disCustomerBos, operationType);
    }

    private List<DisCustomerBo> check(List<DisCustomerBo> disCustomerBos, String operationType) {
        if (Objects.equals(BusTypeEnum.TOTAL_CUSTOMER.getCode(), operationType) ||
                Objects.equals(BusTypeEnum.EXPORT_CUSTOMER.getCode(), operationType)) {
            // 拿手机号去查询t_customer是否存在池子里
            List<String> telLists = disCustomerBos.stream().map(DisCustomerBo::getTel).collect(Collectors.toList());
            QueryWrapper<Customer> customerQuery = Wrappers.query();
            customerQuery.eq("deleted", "0");
            customerQuery.in("tel", telLists);
            customerQuery.select("id, name,tel, task_id, is_reviewe");
            List<CustomerVo> customerVos = customerMapper.selectVoList(customerQuery);
            if (!CollectionUtils.isEmpty(customerVos)) {
                for (CustomerVo customerVo : customerVos) {
                    // 如果存在存在在审件就不能进行操作
                    if (customerVo.getIsReviewe() != -1) {
                        List<DisCustomerBo> collect = disCustomerBos.stream()
                                .filter(s -> customerVo.getTel().equals(s.getTel()))
                                .collect(Collectors.toList());
                        for (DisCustomerBo disCustomerBo : collect) {
                            disCustomerBos.remove(disCustomerBo);
                        }
                    }
                }
            }
        } else {
            // 排除在审件客户
            QueryWrapper<Customer> query = Wrappers.query();
            query.eq("deleted", "0");
            query.in("id", disCustomerBos.stream().map(DisCustomerBo::getId).collect(Collectors.toList()));
            query.select("id, name, tel, distribute_dept_id, is_reviewe, task_id");
            List<CustomerVo> voList = customerMapper.selectVoList(query);
            if (!CollectionUtils.isEmpty(voList)) {
                for (CustomerVo customerVo : voList) {
                    if (customerVo.getIsReviewe() != -1) {
                        List<DisCustomerBo> customerBoList = disCustomerBos.stream()
                                .filter(it -> it.getId().equals(customerVo.getId()))
                                .collect(Collectors.toList());
                        for (DisCustomerBo disCustomerBo : customerBoList) {
                            disCustomerBos.remove(disCustomerBo);
                        }
                    }
                }
            }
        }
        return disCustomerBos;
    }

    @Override
    public List<DisCustomerBo> checkDataUser(DisCustomerRequestBo requestBo, String operationType) {
        // 分配的客户
        List<DisCustomerBo> disCustomerBos = requestBo.getDisCustomerBos();
        if (CollectionUtils.isEmpty(disCustomerBos)) {
            throw new ServiceException("客户信息参数缺失");
        }
        // 分配的用户
        List<DisUserBo> userIds = requestBo.getUserBos();
        if (CollectionUtils.isEmpty(userIds)) {
            throw new ServiceException("用户信息参数缺失");
        }

        return check(disCustomerBos, operationType);
    }

    @Override
    public List<DisVo> dataDealDept(List<DisCustomerBo> customerBos, List<DisDeptBo> deptBos) {
        List<DisVo> disVoList = Lists.newArrayList();
        // 打乱顺序
        Collections.shuffle(customerBos);
        Collections.shuffle(deptBos);
        //总客户数
        Integer clientCount = customerBos.size();
        //总分配人数
        Integer userCount = deptBos.size();
        //余数
        Integer remainderCount = clientCount % userCount;
        //每个人分配数
        Integer divideCount = clientCount / userCount;
        System.out.println("总客户数:" + clientCount + " 总销售数:" + userCount + " 余数:" + remainderCount + " 除数:"
                + divideCount);
        for (int i = 0; i < userCount; i++) {
            for (int j = 0; j <= divideCount; j++) {
                if (userCount * (j) + i <= customerBos.size() - 1) {
                    DisVo disVo = new DisVo();

                    // 部门id
                    disVo.setDeptId(deptBos.get(i).getDeptId());
                    // 部门名称
                    disVo.setDeptName(deptBos.get(i).getDeptName());

                    // 客户id
                    disVo.setId(customerBos.get(userCount * (j) + i).getId());
                    //  客户手机号
                    disVo.setTel(customerBos.get(userCount * (j) + i).getTel());
                    // 客户名称
                    disVo.setName(customerBos.get(userCount * (j) + i).getName());
                    disVoList.add(disVo);
                }
            }
        }
        return disVoList;
    }

    @Override
    public List<DisVo> dataDealUser(List<DisCustomerBo> customerBos, List<DisUserBo> userBos) {
        List<DisVo> disVoList = Lists.newArrayList();
        // 打乱顺序
        Collections.shuffle(customerBos);
        Collections.shuffle(userBos);
        //总客户数
        Integer clientCount = customerBos.size();
        //总分配人数
        Integer userCount = userBos.size();
        //余数
        Integer remainderCount = clientCount % userCount;
        //每个人分配数
        Integer divideCount = clientCount / userCount;
        System.out.println("总客户数:" + clientCount + " 总销售数:" + userCount + " 余数:" + remainderCount + " 除数:"
                + divideCount);
        for (int i = 0; i < userCount; i++) {
            for (int j = 0; j <= divideCount; j++) {
                if (userCount * (j) + i <= customerBos.size() - 1) {
                    DisVo disVo = new DisVo();

                    // 部门id
                    disVo.setUserId(userBos.get(i).getUserId());
                    // 部门名称
                    disVo.setNickName(userBos.get(i).getNickName());

                    disVo.setUserDeptId(userBos.get(i).getUserDeptId());

                    // 客户id
                    disVo.setId(customerBos.get(userCount * (j) + i).getId());
                    //  客户手机号
                    disVo.setTel(customerBos.get(userCount * (j) + i).getTel());
                    // 客户名称
                    disVo.setName(customerBos.get(userCount * (j) + i).getName());
                    disVoList.add(disVo);
                }
            }
        }
        return disVoList;
    }

    private String getCustomerStatus(String type) {
        String customerStatus = "-1";
        String status = sysConfigService.selectConfigByKey("dis.customer.status");
        if (StringUtils.isBlank(status)) {
            return "-1";
        }
        DisStatus disStatus = JsonUtils.parseObject(status, DisStatus.class);
        if (disStatus == null) {
            return "-1";
        }
        switch (type) {
            case "disDept":
                String disDeptStatus = disStatus.getDisDeptStatus();
                if (StringUtils.isNotBlank(disDeptStatus)) {
                    customerStatus = disDeptStatus;
                }
                break;
            case "disUser":
                String disUserStatus = disStatus.getDisUserStatus();
                if (StringUtils.isNotBlank(disUserStatus)) {
                    customerStatus = disUserStatus;
                }
                break;
            default:
                customerStatus = "-1";
                break;
        }
        return customerStatus;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disToDept(List<DisVo> disVos, String operationType, String userName, Long opUserId, Long opDeptId) {
        List<Customer> customers = Lists.newArrayList();
        List<TCustomerDisRecord> disRecords = Lists.newArrayList();
        String customerStatus = getCustomerStatus("disDept");
        if (!CollectionUtils.isEmpty(disVos)) {
            for (DisVo disVo : disVos) {
                String tel = disVo.getTel();
                Long deptId = disVo.getDeptId();

                Long customerId = disVo.getId();
                if (Objects.equals(BusTypeEnum.TOTAL_CUSTOMER.getCode(), operationType) ||
                        Objects.equals(BusTypeEnum.EXPORT_CUSTOMER.getCode(), operationType)) {

                    boolean isCustomer = false;
                    QueryWrapper<Customer> customerQueryInfos = Wrappers.query();
                    customerQueryInfos.eq("deleted", 0);
                    customerQueryInfos.eq("tel", tel);
                    CustomerVo isCustomerInfo = customerMapper.selectVoOne(customerQueryInfos);
                    if (isCustomerInfo != null) {
                        isCustomer = true;
                    }

                    // t_customer 不存在就新增
                    customerMapper.oneKeyIssueCustomer(tel, userName);
                    // 更新总表
                    totalComsterMapper.updateIssueCustomer(tel);

                    QueryWrapper<Customer> customerQueryInfo = Wrappers.query();
                    customerQueryInfo.eq("deleted", 0);
                    customerQueryInfo.eq("tel", tel);
                    CustomerVo customerVo = customerMapper.selectVoOne(customerQueryInfo);
                    if (ObjectUtils.isEmpty(customerVo)) {
                        throw new ServiceException("新增客户信息失败");
                    }

                    customerId = customerVo.getId();

                    String bz = customerVo.getBz();
                    if (StringUtils.isNotBlank(bz) && !isCustomer) {
                        StringBuilder stringBuilder = new StringBuilder();
                        String remarkInfo =
                                bz + "--" + userName + "[" + DateUtils.parseDateToStr(
                                        DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()) + "]";
                        stringBuilder.append(remarkInfo);
                        stringBuilder.append("<br/>");
                        // 更新备注信息到
                        Customer customerInfo = new Customer();
                        customerInfo.setId(customerId);
                        customerInfo.setBz(stringBuilder.toString());
                        customerMapper.updateById(customerInfo);

                        // 新增一条备注记录信息
                        Remark remark = new Remark();
                        remark.setContent(bz);
                        remark.setCustomerId(customerId);
                        remark.setCreateBy(userName);
                        remark.setUserId(opUserId);
                        remarkMapper.insert(remark);
                    }

                }

                // 客户表id
                Customer customer = new Customer();
                customer.setDistributeDeptId(deptId);
                customer.setId(customerId);
                // 公司状态对应  已下发
                // customer.setCustomerStatus(CustomerStatusEnum.XSJ.getCode());
                //customer.setCustomerStatus(CustomerStatusEnum.DGJ.getCode());
                if (!Objects.equals("-1", customerStatus)) {
                    customer.setCustomerStatus(customerStatus);
                }
                customer.setCompanyStatus(CompanyStatusEnum.YXF.getCode());
                customer.setTaskId(-1L);
                customer.setLastRemarkTime(DateUtils.getNowDate());
                customer.setIsNew(0);
                customers.add(customer);

                String name = disVo.getName();
                Long userDeptId = disVo.getUserDeptId();
                // 保存下推记录
                TCustomerDisRecord disRecord = new TCustomerDisRecord();
                disRecord.setBusType(operationType);
                disRecord.setCustomerId(customerId);
                disRecord.setDisName(disVo.getDeptName());
                // 分配给哪个部门
                disRecord.setDisDeptId(userDeptId);
                disRecord.setCustomerName(name);
                // 记录分配记录
                disRecord.setOperateDisId(opUserId);
                disRecord.setOperateDeptId(opDeptId);
                disRecord.setOperateDisName(userName);
                disRecord.setCreateTime(DateUtils.getNowDate());
                disRecords.add(disRecord);
            }
            if (!CollectionUtils.isEmpty(customers)) {
                customerMapper.updateBatchById(customers);
            }
            // 待添加记录信息
            if (!CollectionUtils.isEmpty(disRecords)) {
                disRecordMapper.insertBatch(disRecords);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disToUser(List<DisVo> disVos, String operationType, String userName, Long opUserId, Long opDeptId) {
        List<Customer> customers = Lists.newArrayList();
        List<TCustomerDisRecord> disRecords = Lists.newArrayList();
        String customerStatus = getCustomerStatus("disUser");
        if (!CollectionUtils.isEmpty(disVos)) {
            for (DisVo disVo : disVos) {
                String tel = disVo.getTel();
                Long totalCustomerId = disVo.getId();
                Long userId = disVo.getUserId();

                Long customerId = disVo.getId();
                if (Objects.equals(BusTypeEnum.TOTAL_CUSTOMER.getCode(), operationType) ||
                        Objects.equals(BusTypeEnum.EXPORT_CUSTOMER.getCode(), operationType)) {
                    boolean isCustomer = false;
                    QueryWrapper<Customer> customerQueryInfos = Wrappers.query();
                    customerQueryInfos.eq("deleted", 0);
                    customerQueryInfos.eq("tel", tel);
                    CustomerVo isCustomerInfo = customerMapper.selectVoOne(customerQueryInfos);
                    if (isCustomerInfo != null) {
                        isCustomer = true;
                    }

                    customerMapper.oneKeyIssueCustomer(tel, userName);
                    totalComsterMapper.updateCustomer(totalCustomerId);

                    QueryWrapper<Customer> customerQueryInfo = Wrappers.query();
                    customerQueryInfo.eq("deleted", 0);
                    customerQueryInfo.eq("tel", tel);
                    CustomerVo customerVo = customerMapper.selectVoOne(customerQueryInfo);
                    if (ObjectUtils.isEmpty(customerVo)) {
                        throw new ServiceException("新增客户信息失败");
                    }
                    String bz = customerVo.getBz();
                    customerId = customerVo.getId();

                    if (StringUtils.isNotBlank(bz) && !isCustomer) {
                        StringBuilder stringBuilder = new StringBuilder();
                        String remarkInfo =
                                bz + "--" + userName + "[" + DateUtils.parseDateToStr(
                                        DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()) + "]";
                        stringBuilder.append(remarkInfo);
                        stringBuilder.append("<br/>");
                        // 更新备注信息到
                        Customer customerInfo = new Customer();
                        customerInfo.setId(customerId);
                        customerInfo.setBz(stringBuilder.toString());
                        customerMapper.updateById(customerInfo);

                        // 新增一条备注记录信息
                        Remark remark = new Remark();
                        remark.setContent(bz);
                        remark.setCustomerId(customerId);
                        remark.setCreateBy(userName);
                        remark.setUserId(opUserId);
                        remarkMapper.insert(remark);
                    }
                }

                // 客户表id
                Customer customer = new Customer();
                customer.setDistributeDeptId(disVo.getUserDeptId());
                if (!Objects.equals("-1", customerStatus)) {
                    customer.setCustomerStatus(customerStatus);
                }
                // 公司状态为 待认领

                customer.setCompanyStatus(CompanyStatusEnum.DRL.getCode());
                // 用户ID写入
                customer.setTaskId(userId);
                customer.setId(customerId);
                // 更新时间
                customer.setLastRemarkTime(DateUtils.getNowDate());

                customer.setIsPush("0");
                // 分配之前就是新数据
                customer.setIsNew(1);
                customers.add(customer);

                // 保存下推记录
                TCustomerDisRecord disRecord = new TCustomerDisRecord();
                disRecord.setBusType(operationType);
                disRecord.setCustomerId(customerId);
                // 分配给哪个部门
                disRecord.setDisDeptId(disVo.getUserDeptId());
                disRecord.setDisUserId(userId);
                disRecord.setDisName(disVo.getNickName());
                disRecord.setTaskId(disVo.getTaskId());
                disRecord.setCustomerName(disVo.getName());
                // 记录分配记录
                disRecord.setOperateDisId(opUserId);
                disRecord.setOperateDeptId(opDeptId);
                disRecord.setOperateDisName(userName);
                disRecord.setCreateTime(DateUtils.getNowDate());
                disRecords.add(disRecord);
            }
            if (!CollectionUtils.isEmpty(customers)) {
                customerMapper.updateBatchById(customers);
            }
            // 记录下发信息
            if (!CollectionUtils.isEmpty(disRecords)) {
                disRecordMapper.insertBatch(disRecords);
            }
        }
    }

    /**
     * @param userId
     * @return
     */
    @Override
    public Integer isAbleDisCustomerToUser(String userId) {
        return customerMapper.getUserCustomerCount(userId);
    }


    @Override
    public Map<String, Object> userDataDeal(List<DisVo> disVos) {
        Map<String, Object> map = new HashMap<>();
        map.put("success", Lists.newArrayList());
        map.put("fail", Lists.newArrayList());
        map.put("unDis", Lists.newArrayList());
        List<DisVo> successDis = new ArrayList<>();
        List<String> buNameList = new ArrayList<>();
        List<DisVo> failDis = new ArrayList<>();
        if (!CollectionUtils.isEmpty(disVos)) {
            String userInfoStr = disVos.stream().map(it -> String.valueOf(it.getUserId()))
                    .distinct()
                    .collect(Collectors.joining(","));
            // 业务员现在的数据统计
            List<UserCustomerCount> userCountList = customerMapper.getUserCount(userInfoStr);
            Map<Long, Integer> userCount = disVos.stream()
                    .collect(Collectors.toMap(DisVo::getUserId, el -> 1, Integer::sum));

            for (UserCustomerCount userCustomerCount : userCountList) {
                Long userId = userCustomerCount.getUserId();
                String busName = userCustomerCount.getBusName();
                // 不为空
                if (!userCount.isEmpty()) {
                    // 分配数量
                    Integer disCount = userCount.get(userId);
                    // 已有数量
                    Integer countSum = userCustomerCount.getCountSum();
                    // 总共的数量
                    Integer count = countSum + disCount;
                    if (countSum >= 300) {
                        buNameList.add(busName);
                        // 待处理信息
                        failDis.addAll(disVos.stream().filter(it -> it.getUserId().equals(userId))
                                .collect(Collectors.toList()));
                    } else if (count > 300) {
                        buNameList.add(busName);
                        // 超出了 截取可分配的数量
                        Integer able = 300 - countSum;
                        failDis.addAll(disVos.stream().filter(it -> it.getUserId().equals(userId)).skip(able)
                                .collect(Collectors.toList()));
                        successDis.addAll(disVos.stream().filter(it -> it.getUserId().equals(userId)).limit(able)
                                .collect(Collectors.toList()));
                    } else {
                        successDis.addAll(disVos.stream().filter(it -> it.getUserId().equals(userId))
                                .collect(Collectors.toList()));
                    }
                }
            }
        }
        map.put("success", successDis);
        map.put("fail", failDis);
        map.put("unDis", buNameList);
        return map;
    }


    /**
     * 异步发送消息
     */
    @Override
    public void sentInfo(String type, Map<String, Object> map) {
        SentMessage send = new SentMessage();
        send.setType(type);
        List<DisVo> disVos = (List<DisVo>) map.get("fail");
        List<String> unDis = (List<String>) map.get("unDis");
        if (CollectionUtils.isEmpty(disVos)) {
            return;
        }
        String content = "已满300业务员：" + String.join(",", unDis) + "<br>" +
                "未分配客户：" + disVos.stream().map(it -> {
            return (StringUtils.isNotBlank(it.getName()) ? it.getName() : "") + "【" + it.getTel() + "】";
        }).collect(Collectors.joining(","));
        Map<String, String> mapInfo = new HashMap<>();
        mapInfo.put("info", content);
        send.setContent(JSONObject.toJSONString(mapInfo));

        List<String> userList = new ArrayList<>();
        userList.add(String.valueOf(""));
        send.setUserIds(userList);
        send.setOperationName("");
        SpringUtils.context().publishEvent(send);
    }

    @Override
    public void channelChannelDis(SentMessage send) {
        SpringUtils.context().publishEvent(send);
    }
}
